using System.Globalization;
using System.Text;
using Abp.Dependency;
using Abp.Extensions;
using Abp.Web;
using Abp.Web.Api.Modeling;
using Abp.Web.Api.ProxyScripting.Generators;

namespace Xugege.AbpExtension.Web.Core.Extension.Controllers.Scripts.Angular
{
    public class AngularProxyGenerator : IProxyScriptGenerator, ITransientDependency
    {

        public const string Name = "angular";

        public string CreateScript(ApplicationApiDescriptionModel model)
        {
            var script = new StringBuilder();
            script.AppendLine("(function (abp, angular) {");
            script.AppendLine("");
            script.AppendLine("    if (!angular) {");
            script.AppendLine("        return;");
            script.AppendLine("    }");
            script.AppendLine("    ");
            script.AppendLine("    var abpModule = angular.module('abp');");
            foreach (var module in model.Modules.Values)
            {
                script.AppendLine($"//module '{module.Name}'");
                AddModuleScript(script, module);
            }
            script.AppendLine();
            script.AppendLine();
            script.AppendLine("})((abp || (abp = {})), (angular || undefined));");
            return script.ToString();
        }

        private static void AddModuleScript(StringBuilder script, ModuleApiDescriptionModel module)
        {

            foreach (var controller in module.Controllers.Values)
            {
                script.AppendLine($"//controller {controller.Name.ToCamelCase()}");
                script.AppendLine();
                script.AppendLine("    abpModule.factory('abp.services." + module.Name.ToCamelCase() + "." + controller.Name.ToCamelCase() + "', [");
                script.AppendLine("        '$http', function ($http) {");
                script.AppendLine("            return new function () {");

                foreach (var action in controller.Actions.Values)
                {
                    script.AppendLine();
                    script.AppendLine($"//action {action.Name.ToCamelCase()}");
                    AddActionScript(script, module, controller, action);
                }

                
                script.AppendLine("        }");
                script.AppendLine("    ]);");
                script.AppendLine();
            }



        }

        private static void AddActionScript(StringBuilder script, ModuleApiDescriptionModel module, ControllerApiDescriptionModel controller, ActionApiDescriptionModel action)
        {
            var httpMethod = action.HttpMethod?.ToUpperInvariant() ?? "POST";
            var parameterList = ProxyScriptingJsFuncHelperExtesion.GenerateJsFuncParameterList(action, "angularAjaxParams");
            script.AppendLine("                this." + action.Name.ToCamelCase() + " = function (" + parameterList + ") {");
            script.AppendLine("                    return $http(angular.extend({");
            script.AppendLine("                        url: abp.appPath + '" + ProxyScriptingHelperExtesion.GenerateUrlWithParameters(action) + "',");
            script.AppendLine("                        method: '" + httpMethod + "',");
            //var body = ProxyScriptingHelperExtesion.GenerateBody(action);
            //if (httpMethod.ToLower() == "get")
            //{
            //    script.AppendLine("                        params: " + (string.IsNullOrEmpty(body) ? "null" : body));
            //}
            //else
            //{
            //    script.AppendLine("                        data: JSON.stringify(" + body + ")");
            //}

            GenerateBody(script, action, httpMethod.ToLower());

            script.AppendLine("");
            script.AppendLine("            };");
        }

        private static void GenerateBody(StringBuilder script, ActionApiDescriptionModel action, string httpMethod)
        {
            if (httpMethod == "get")
            {
                var body = ProxyScriptingHelperExtesion.GenerateBody(action);
                if (!body.IsNullOrEmpty())
                {
                    script.Append($"                        params: {body}");
                }
                else
                {
                    script.Append("                        params: null");
                }
            }
            else
            {
                var body = ProxyScriptingHelperExtesion.GenerateBody(action);
                if (!body.IsNullOrEmpty())
                {
                    script.Append("                        data: JSON.stringify(" + body + ")");
                }
                else
                {
                    var formData = ProxyScriptingHelperExtesion.GenerateFormPostData(action, 8);
                    if (!formData.IsNullOrEmpty())
                    {

                        script.Append("                        data: " + formData);
                    }
                    else
                    {
                        script.Append("                        data: {}" );
                    }
                }
            }

        }
    }


}